<?php
/**
 * Dirox Framework
 * Copyright (C) 2008 - 2009 Dirox
 * 
 * All rights reserved.
 */

class DRX_RequestHandler
{
	/**
	 * Array holding all request parameters
	 */
	static protected $_request_data = array();

	/**
	 * Initialization function (static constructor)
	 * This function will extract parameters from the user query
	 * and build an unified parameters array.
	 *
	 * @param string The order in which to construct the parameters array
	 *   G stands for GET, P for POST, A for URL user arguments and C for command line (argv arguments)
	 *   knowing that the last will override parameters with the same name
	 *   it can be useful to tweak the order in some condition
	 *   Note that the code is optimized for default loading scheme (GPA)
	 */
	static function initialize($construction_order = 'GPA')
	{
		// Extract parameters from the query
		$arrArgs = array();
		if ($pos = strpos($_SERVER['REQUEST_URI'], "?"))
		{
			$args = substr($_SERVER['REQUEST_URI'],$pos+1 );
			if (trim($args)!="")
			{
				$exps = explode("&",$args);
				foreach ($exps as $exp) 
				{
					$arg = explode("=", $exp);
					
					$arg[1] = urldecode($arg[1]);
					
					$_GET[$arg[0]] = $arg[1];
					$_REQUEST[$arg[0]] = $arg[1];
				}
			}
			
			DRX::register("args", $args);
			DRX::register("decoded_requesturl", substr($_SERVER['REQUEST_URI'], 0, $pos + 1) . $args);
		}
		else 
		{
			DRX::register("decoded_requesturl", $_SERVER['REQUEST_URI']);
		}
		
		$_SERVER['REQUEST_URI'] = urldecode($_SERVER['REQUEST_URI']);

		// Construct CLI arguments
		global $argv;
		$cliArgs = array();
		if (isset($argv))
		{
			array_shift($argv);
			$nb_arg = count($argv);
			$numeric_index = 0;

			for ($i = 0; $i < $nb_arg; ++$i)
			{
				if (substr($argv[$i],0,2) === '--')
				{
					$arr = explode('=',substr($argv[$i],2),2);
					// Did we use an equal sign to separate arg name and value?
					if(count($arr) > 1)
					{
						$cliArgs[$arr[0]] = $arr[1];
					}
					else
					{
						// The next element of argv (if existing) is the value
						if (++$i < $nb_arg)
						{
							$cliArgs[$arr[0]] = $argv[$i];
						}
						else
						{
							$cliArgs[$arr[0]] = '';
						}
					}
				}
				elseif (substr($argv[$i],0,1) === '-')
				{
					$cliArgs[strval(substr($argv[$i],1))] = true;
				}
				else
				{
					switch($numeric_index++)
					{
						case 0 :
							$cliArgs['m'] = $argv[$i];
							break;
						case 1 :
							$cliArgs['a'] = $argv[$i];
							break;
						default :
							$cliArgs[$numeric_index-1] = $argv[$i];
							break;
					}
				}
			}
		}

		if ($construction_order != 'GPA')
		{
			$construction_order = preg_replace('/[^GPAC]/','',$construction_order);
			$construction_order = preg_replace('/(.)(?=.)/','$1,',$construction_order);
			$construction_order = str_replace(array('G','P','A','C'),array('$_GET','$_POST','$arrArgs','$cliArgs'),$construction_order);
			self::$_request_data = eval('return array_merge('.$construction_order.');');
		}
		else
		{
			self::$_request_data = array_merge($_GET,$_POST,$arrArgs);
		}
	}

	/**
	 * Returns the full parameters array constructed from the request
	 */
	static function getParametersArray()
	{
		return self::$_request_data;
	}

	/**
	 * Return true if the param $varnam is set in the request data
	 * false otherwise
	 */
	static function isParamSet($varname)
	{
		return array_key_exists($varname,self::$_request_data);
	}


	/**
	 * Return the value of the parameter named $varname as it is in the
	 * request.
	 * If not set in the request variables, we return the second parameter
	 * (default return value)
	 *
	 * @param string the name of the parameter to get
	 * @param mixed the value to return if the parameter is not set
	 */
	static function get($varname,$default = FALSE)
	{
		return self::isParamSet($varname) ? self::$_request_data[$varname] : $default;

	}

	/**
	 * Return the value of the parameter named $varname if it's a number.
	 * If not set in the request variables, or with a wrong type,
	 * we return the second parameter
	 *
	 * @param string the name of the number parameter to get
	 * @param mixed the value to return if the parameter is not set
	 *   or is of the wrong type.
	 */
	static function getNumber($varname, $default = 0)
	{
		$str_value = self::get($varname,$default);

		return is_numeric($str_value) ? $str_value+0 : $default;
	}

	/**
	 * Return the value of the parameter named $varname if it's an int.
	 * If not set in the request variables, or with a wrong type,
	 * we return the second parameter
	 *
	 * @param string the name of the int parameter to get
	 * @param mixed the value to return if the parameter is not set
	 *   or is of the wrong type.
	 */
	static function getIntNumber($varname, $default = 0)
	{
		$val = self::getNumber($varname,$default);

		// If it's not the default value, we return it intvalued
		if ($val !== $default)
		{
			return intval($val);
		}
		else
		{
			return $val;
		}
	}

	/**
	 * Return the string value of the parameter named $varnam
	 * or $default if it's not set
	 */
	static function getString($varname,$default = '')
	{
		if (self::isParamSet($varname))
		{
			return strval(self::get($varname));
		}
		else
		{
			return $default;
		}
	}

	/**
	 * Return the boolean value of the var named $varname. Accepted possible
	 * request variable values are :
	 *   'true', 'false', 'on' (gives true), 0 (gives false), integer != 0 (gives true)
	 *
	 * If not set in the request variables, we return the second parameter
	 * (default return value)
	 *
	 * @param string the name of the boolean parameter to get
	 * @param mixed the value to return if the parameter is not set or
	 *   does not evaluate as a boolean
	 */
	static function getBoolean($varname,$default = false)
	{
		$val = self::get($varname);

		if (strcasecmp($val,'true') == 0 or strcasecmp($val,'on') == 0)
		{
			return true;
		}
		elseif (strcasecmp($val,'false') == 0)
		{
			return false;
		}
		elseif (is_numeric($val))
		{
			return ($val+0) != 0;
		}
		else
		{
			return $default;
		}
	}

	/**
	 * Return the date value of the var named $varname.
	 * validated against the format and converted to the
	 * the given output format. If the validation failed,
	 * or if the param has not been sent,
	 * this function returns FALSE.
	 *
	 * For the definition of format strings,
	 * @link http://php.net/date
	 * Note that we're using a subset of the format modfier, containing :
	 * (d,j,m,n,y,Y,a,A,g,G,h,H,i,s) + some specials (F,S)
	 * All date characters must be prefixed by a % sign (like %a, %y)
	 */
	static function getDateTime($varname,$in_format = 'Y-m-d', $out_format = FALSE)
	{
		$val = self::getString($varname);

		// Gain some time, return false if the string is empty
		if ($val == '')
		{
			return FALSE;
		}

		// Validate the input format
		if ( ($date = DRX_DateTimeUtils::parseDate($val,$in_format)) !== FALSE )
		{
			if ($out_format === FALSE or $out_format == $in_format)
			{
				return $val;
			}
			else
			{
				return DRX_DateTimeUtils::formatDate($date,$out_format);
			}
		}

		return FALSE;
	}
}
?>
